package com.dynabook.ems.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.dynabook.ems.common.BaseResponse;
import com.dynabook.ems.common.ErrorCode;
import com.dynabook.ems.common.ResultUtils;
import com.dynabook.ems.mapstruct.EbsTOEbsDataMapper;
import com.dynabook.ems.mapstruct.EbsToMainEngineMapper;
import com.dynabook.ems.model.dto.FromEBSData;
import com.dynabook.ems.model.entity.EmsAbnormal;
import com.dynabook.ems.model.entity.EmsEbsData;
import com.dynabook.ems.model.entity.EmsMainEngine;
import com.dynabook.ems.model.enums.ModelStatusEnum;
import com.dynabook.ems.model.vo.CheckOAFirstVO;
import com.dynabook.ems.service.EbsSyncService;
import com.dynabook.ems.service.EmsAbnormalService;
import com.dynabook.ems.service.EmsEbsDataService;
import com.dynabook.ems.service.EmsMainEngineService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class EbsSyncServiceImpl implements EbsSyncService {

    @Value("${spring.ebs_url}")
    private String EBS_URL;

    @Value("${spring.oa_url}")
    private String OA_URL;

    @Resource
    private EmsMainEngineService emsMainEngineService;

    @Resource
    private EmsEbsDataService emsEbsDataService;

    @Resource
    private EmsAbnormalService emsAbnormalService;

    // 定义常量，避免硬编码
    private static final int HTTP_TIMEOUT = 10000;
    private static final String CONTENT_TYPE_JSON = "application/json";

    @Override
    public BaseResponse executeTimingTaskFromEbs() {
        log.info("========== 开始执行EBS数据同步定时任务 ==========");
        String EBS_URL_FULL_PATH = EBS_URL + "getEBSData";
        String OA_URL_FULL_PATH = OA_URL + "checkOAFirst";
        String EBS_UPDATE_FLAG = EBS_URL + "updateFlag";
        
        log.info("EBS数据请求URL: {}", EBS_URL_FULL_PATH);
        log.info("OA校验请求URL: {}", OA_URL_FULL_PATH);
        log.info("EBS更新标志URL: {}", EBS_UPDATE_FLAG);

        List<Long> sequenceIds = new ArrayList<>();

        try {
            // 获取EBS数据
            log.info("开始请求EBS数据，URL: {}", EBS_URL_FULL_PATH);
            HttpResponse response = HttpRequest.get(EBS_URL_FULL_PATH)
                    .timeout(HTTP_TIMEOUT)
                    .execute();

            log.info("EBS请求响应状态码: {}", response.getStatus());
            
            // 检查HTTP状态码是否为200
            if (response.getStatus() != 200) {
                log.error("EBS请求失败，HTTP状态码: {}", response.getStatus());
                return ResultUtils.error(ErrorCode.SYSTEM_ERROR.getCode(), "EBS请求失败");
            }

            // 获取响应体内容
            String responseBody = response.body();
            if (responseBody == null || responseBody.isEmpty()) {
                log.warn("请求成功，但返回空数据");
                return ResultUtils.error(ErrorCode.SYSTEM_ERROR.getCode(), "请求成功，但返回空数据");
            }

            log.info("EBS请求成功，响应体长度: {} 字符", responseBody.length());
            JSONObject jsonObject = JSONUtil.parseObj(responseBody);
            
            // 检查data字段是否存在
            if (!jsonObject.containsKey("data") || !(jsonObject.get("data") instanceof JSONArray)) {
                log.warn("EBS返回数据格式不正确，缺少data数组字段，完整响应: {}", responseBody);
                return ResultUtils.error(ErrorCode.SYSTEM_ERROR.getCode(), "EBS返回数据格式不正确，缺少data数组字段");
            }
            
            JSONArray dataArray = jsonObject.getJSONArray("data");
            int dataCount = dataArray.size();
            log.info("EBS返回数据条数: {}", dataCount);
            
            ArrayList<String> list = new ArrayList<>();
            int successCount = 0;
            int skipCount = 0;
            
            // 处理每条EBS数据
            for (int i = 0; i < dataArray.size(); i++) {
                Object item = dataArray.get(i);
                log.info("========== 开始处理第 {}/{} 条EBS数据 ==========", i + 1, dataCount);
                log.debug("原始数据内容: {}", item);
                
                FromEBSData fromEBSData = JSONUtil.toBean(item.toString(), FromEBSData.class);
                if (fromEBSData == null) {
                    log.error("请求到的ebs数据为空，原始数据: {}", item);
                    skipCount++;
                    continue;
                }

                log.info("解析EBS数据成功，oaRequestId: {}, sequenceId: {}, sn: {}, pno: {}", 
                        fromEBSData.getOaRequestId(), fromEBSData.getSequenceId(), 
                        fromEBSData.getSn(), fromEBSData.getPno());

                // 检查关键字段
                if (fromEBSData.getOaRequestId() == null || fromEBSData.getSequenceId() == null) {
                    log.error("EBS数据缺少必要字段，oaRequestId: {}, sequenceId: {}, 原始数据: {}", 
                            fromEBSData.getOaRequestId(), fromEBSData.getSequenceId(), item);
                    skipCount++;
                    continue;
                }

                // 发起OA校验
                log.info("开始处理OA校验，oaRequestId: {}, sequenceId: {}", 
                        fromEBSData.getOaRequestId(), fromEBSData.getSequenceId());
                String message = processOAVerification(fromEBSData, OA_URL_FULL_PATH, sequenceIds);
                list.add(message);
                
                if (message != null && !message.isEmpty()) {
                    log.info("OA校验处理完成，消息: {}", message);
                }
                successCount++;
                log.info("========== 第 {}/{} 条EBS数据处理完成 ==========", i + 1, dataCount);
            }

            log.info("EBS数据处理完成，总计: {} 条，成功处理: {} 条，跳过: {} 条", 
                    dataCount, successCount, skipCount);

            // 更新EBS标志
            if (!sequenceIds.isEmpty()) {
                log.info("开始更新EBS标志，需要更新的sequenceId数量: {}", sequenceIds.size());
                log.info("需要更新的sequenceId列表: {}", sequenceIds);
                updateEbsFlags(sequenceIds, EBS_UPDATE_FLAG);
            } else {
                log.info("没有需要更新EBS标志的数据，sequenceIds为空");
            }
            
            log.info("========== EBS数据同步定时任务执行完成 ==========");
            return ResultUtils.success(list);
        } catch (Exception e) {
            log.error("调用EBS接口失败: ", e);
            return ResultUtils.error(ErrorCode.SYSTEM_ERROR.getCode(),"调用EBS接口失败");
        }
    }

    /**
     * 处理OA验证
     */
    private String processOAVerification(FromEBSData fromEBSData, String oaUrlFullPath, List<Long> sequenceIds) {
        String message= "";
        String requestId = fromEBSData.getOaRequestId();
        Long sequenceId = fromEBSData.getSequenceId();
        
        log.info("开始OA验证流程，oaRequestId: {}, sequenceId: {}", requestId, sequenceId);
        
        try {
            JSONObject params = new JSONObject();
            params.set("requestId",requestId);
            String requestBody = JSONUtil.toJsonStr(params);
            log.info("OA校验请求参数: {}, 请求URL: {}", requestBody, oaUrlFullPath);
            
            HttpResponse oaResponse = HttpRequest.post(oaUrlFullPath)
                    .header(Header.CONTENT_TYPE, CONTENT_TYPE_JSON)
                    .body(requestBody)
                    .timeout(HTTP_TIMEOUT)
                    .execute();

            log.info("OA校验请求完成，oaRequestId: {}, HTTP状态码: {}", requestId, oaResponse.getStatus());

            if (oaResponse.getStatus() != 200) {
                log.error("OA请求失败，oaRequestId: {}, HTTP状态码: {}, 响应体: {}", 
                        requestId, oaResponse.getStatus(), oaResponse.body());
                return null;
            }

            String returnStatus = oaResponse.body();
            if (returnStatus == null || returnStatus.isEmpty()) {
                log.warn("OA请求成功，但返回空数据，oaRequestId: {}", requestId);
                return null;
            }

            log.info("OA校验响应内容，oaRequestId: {}, 响应体: {}", requestId, returnStatus);
            JSONObject oaStatus = JSONUtil.parseObj(returnStatus);
            
            if (!oaStatus.containsKey("data")) {
                log.warn("OA返回数据格式不正确，缺少data字段，oaRequestId: {}, 完整响应: {}", 
                        requestId, returnStatus);
                return null;
            }
            
            CheckOAFirstVO checkOAFirstVO=JSONUtil.toBean(oaStatus.getStr("data"), CheckOAFirstVO.class);
//            CheckOAFirstVO checkOAFirstVO=oaStatus.getBean("data",CheckOAFirstVO.class);
//            Boolean oaFlag = Boolean.valueOf(oaStatus.getStr("data"));
            
            log.info("OA校验结果解析完成，oaRequestId: {}, flag: {}, oaRequestIdFromOA: {}", 
                    requestId, checkOAFirstVO.getFlag(), checkOAFirstVO.getOaRequestId());
            
            if (checkOAFirstVO.getFlag()) {
                log.info("OA校验通过，开始保存EBS数据，oaRequestId: {}, sequenceId: {}", requestId, sequenceId);
                // 使用事务保证数据一致性
                saveEbsData(fromEBSData,checkOAFirstVO.getOaRequestId());
                sequenceIds.add(fromEBSData.getSequenceId());
                log.info("EBS数据保存成功，已添加到更新列表，oaRequestId: {}, sequenceId: {}", 
                        requestId, sequenceId);
            } else {
                log.warn("OA校验未通过，flag为false，oaRequestId: {}, 开始保存异常记录", requestId);
                message= saveAbnormalRecord(fromEBSData, 0,"",1);
                log.error("OA中不存在ebs的requestId:{},错误信息为:{}", requestId, message);
            }

            log.info("OA验证流程完成，oaRequestId: {}, 校验结果: {}, 响应数据: {}",
                    requestId, checkOAFirstVO.getFlag(), oaStatus.getStr("data"));
        } catch (Exception e) {
            log.error("处理OA验证时发生错误，oaRequestId: {}, sequenceId: {}, 错误信息: {}", 
                    requestId, sequenceId, e.getMessage(), e);
        }
        return message;
    }

    /**
     * 保存EBS数据到数据库
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveEbsData(FromEBSData fromEBSData,String oaRequestId) {
        log.info("========== 开始保存EBS数据到数据库 ==========");
        log.info("保存数据，oaRequestId: {}, sequenceId: {}, sn: {}, pno: {}, bigCategory: {}", 
                oaRequestId, fromEBSData.getSequenceId(), fromEBSData.getSn(), 
                fromEBSData.getPno(), fromEBSData.getBigCategory());
        
        String fixNo = emsMainEngineService.getFixNo();
        log.info("获取到fixNo: {}", fixNo);
        
        EmsMainEngine emsMainEngine = EbsToMainEngineMapper.INSTANCE.EbsToMainEngine(fromEBSData);
        EmsEbsData emsEbsData = EbsTOEbsDataMapper.INSTANCE.EbsTOEbsData(fromEBSData);
        log.info("数据映射完成，emsMainEngine和emsEbsData对象已创建");
        
        emsEbsData.setGoodstype("I");
        emsEbsData.setFixedNo(fixNo);
        log.info("设置emsEbsData，goodstype: I, fixedNo: {}", fixNo);
        
        String sn = fromEBSData.getSn();
        String pno = fromEBSData.getPno();
        log.info("提取关键字段，sn: {}, pno: {}", sn, pno);
        
        //        如果是整机设置型号为pno号,不是整机设置为itemcode
        String type = "";
        if (!fromEBSData.getBigCategory().equals("Machine")) {
            type = fromEBSData.getItemCode();
            log.info("非整机类型，设置type为itemCode: {}", type);
        } else {
//            整机
            type = pno;
            log.info("整机类型，设置type为pno: {}", type);
        }
        emsMainEngine.setType(type);
        log.info("最终设置的type值: {}", type);
        
        if(StrUtil.isNotBlank(sn)){
            log.info("SN号不为空，开始检查SN号是否已存在，sn: {}", sn);
            Boolean isExistSn = emsMainEngineService.isExistSn(sn);
            log.info("SN号存在性检查结果，sn: {}, isExistSn: {}", sn, isExistSn);
            
            if(isExistSn){
                log.info("sn号已存在,SN号为:{}",sn);
                emsMainEngine.setIsRepeat(1);
                emsMainEngine.setRepeatMessage("sn号已存在,SN号为:"+sn);
                log.warn("检测到SN号重复，设置isRepeat=1，sn: {}", sn);
            }else{
                log.info("SN号不存在，继续检查型号和流程号是否重复，type: {}, oaRequestId: {}", type, oaRequestId);
                Boolean isExistTypeAndSerialNumber = emsMainEngineService.isExistTypeAndSerialNumber(type,oaRequestId);
                log.info("型号和流程号重复性检查结果，type: {}, oaRequestId: {}, isExistTypeAndSerialNumber: {}", 
                        type, oaRequestId, isExistTypeAndSerialNumber);
                
                if(isExistTypeAndSerialNumber){
                    emsMainEngine.setIsRepeat(2);
                    emsMainEngine.setRepeatMessage("样品型号和流程号重复,分别为:"+type+","+oaRequestId);
                    log.warn("检测到型号和流程号重复，设置isRepeat=2，type: {}, oaRequestId: {}", type, oaRequestId);
                } else {
                    log.info("型号和流程号不重复，数据正常");
                }
            }
        }else {
            log.info("SN号为空，直接检查型号和流程号是否重复，type: {}, oaRequestId: {}", type, oaRequestId);
            Boolean isExistTypeAndSerialNumber = emsMainEngineService.isExistTypeAndSerialNumber(type,oaRequestId);
            log.info("型号和流程号重复性检查结果，type: {}, oaRequestId: {}, isExistTypeAndSerialNumber: {}", 
                    type, oaRequestId, isExistTypeAndSerialNumber);
            
            if(isExistTypeAndSerialNumber){
                emsMainEngine.setIsRepeat(2);
                emsMainEngine.setRepeatMessage("样品型号和流程号重复,分别为:"+type+","+oaRequestId);
                log.warn("检测到型号和流程号重复，设置isRepeat=2，type: {}, oaRequestId: {}", type, oaRequestId);
            } else {
                log.info("型号和流程号不重复，数据正常");
            }
        }
        
//        是否是part
        if(!fromEBSData.getBigCategory().equals("Part")){
            emsMainEngine.setInventoryNum(1);
            emsMainEngine.setTotalNum(1);
            log.info("非Part类型，设置库存数量和总数量为1，bigCategory: {}", fromEBSData.getBigCategory());
        }else{
            int quantity = Math.toIntExact(fromEBSData.getQuantity());
            emsMainEngine.setInventoryNum(quantity);
            emsMainEngine.setTotalNum(quantity);
            log.info("Part类型，设置库存数量和总数量为quantity，quantity: {}", quantity);
        }
        
        emsMainEngine.setInstoreDate(LocalDateTime.now());
        emsMainEngine.setBigCategory(fromEBSData.getBigCategory());
        emsMainEngine.setCategory(fromEBSData.getCategory());
        emsMainEngine.setUsedNum(0);
        emsMainEngine.setScrapNum(0);
        emsMainEngine.setFixedNo(fixNo);
        emsMainEngine.setSerialNo(sn);
        emsMainEngine.setModelStatus(ModelStatusEnum.BEFORE_EDIT.getValue());
        emsMainEngine.setSerialNumber(oaRequestId);
        emsMainEngine.setOaRequestId(oaRequestId);
        
        log.info("emsMainEngine属性设置完成，准备保存到数据库");
        log.debug("emsMainEngine详细信息 - type: {}, sn: {}, oaRequestId: {}, fixNo: {}, isRepeat: {}, bigCategory: {}, category: {}", 
                type, sn, oaRequestId, fixNo, emsMainEngine.getIsRepeat(), 
                fromEBSData.getBigCategory(), fromEBSData.getCategory());
        
        emsMainEngineService.save(emsMainEngine);

        emsEbsDataService.saveOrUpdate(emsEbsData);
        log.info("emsEbsData保存或更新成功");
        
        log.info("开始更新异常记录状态，oaRequestId: {}, fixNo: {}", oaRequestId, fixNo);
        String abnormalMessage = saveAbnormalRecord(fromEBSData, 1,fixNo,2);
        log.info("异常记录更新完成，消息: {}", abnormalMessage);
        
        log.info("========== EBS数据保存完成，oaRequestId: {}, sequenceId: {} ==========", 
                oaRequestId, fromEBSData.getSequenceId());
    }

    /**
     * 保存异常记录
     */
    private String saveAbnormalRecord(FromEBSData fromEBSData, int status, String fixNo, int type) {
        String oaRequestId = fromEBSData.getOaRequestId();
        Long sequenceId = fromEBSData.getSequenceId();
        String message = oaRequestId + "在OA系统中不存在";
        
        log.info("开始处理异常记录，oaRequestId: {}, sequenceId: {}, status: {}, fixNo: {}, type: {}", 
                oaRequestId, sequenceId, status, fixNo, type);
        
        // 查询数据库中是否存在对应的记录
        QueryWrapper<EmsAbnormal> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("oa_request_id", oaRequestId);
        log.info("查询异常记录，查询条件: oa_request_id = {}", oaRequestId);
        
        EmsAbnormal existingRecord = emsAbnormalService.getOne(queryWrapper);
        log.info("异常记录查询结果，oaRequestId: {}, 是否存在: {}", oaRequestId, existingRecord != null);
        
        if (type == 1) {
            log.info("处理type=1的情况：有记录就不做任何操作，没有记录就插入");
            // type=1: 有记录就不做任何操作，没有记录就插入
            if (existingRecord != null) {
                // 记录已存在，不做任何操作
                log.info("异常记录已存在，跳过插入操作，oaRequestId: {}, 现有记录id: {}", 
                        oaRequestId, existingRecord.getId());
                return oaRequestId + "记录已存在，跳过插入操作";
            } else {
                // 记录不存在，插入新记录
                log.info("异常记录不存在，开始插入新记录，oaRequestId: {}, sequenceId: {}", oaRequestId, sequenceId);
                EmsAbnormal emsAbnormal = new EmsAbnormal();
                emsAbnormal.setOaRequestId(oaRequestId);
                emsAbnormal.setType(type);
                emsAbnormal.setMessage(message);
                emsAbnormal.setSequenceId(Math.toIntExact(sequenceId));
                emsAbnormal.setStatus(status);
                emsAbnormal.setFixedNo(fixNo);
                
                log.info("准备插入异常记录，详细信息 - oaRequestId: {}, type: {}, status: {}, sequenceId: {}, fixNo: {}, message: {}", 
                        oaRequestId, type, status, sequenceId, fixNo, message);
                
                boolean saved = emsAbnormalService.save(emsAbnormal);
                if (saved) {
                    log.info("异常记录插入成功，oaRequestId: {}, 记录id: {}", oaRequestId, emsAbnormal.getId());
                    return oaRequestId + "新记录插入成功";
                } else {
                    log.error("异常记录插入失败，oaRequestId: {}", oaRequestId);
                    return oaRequestId + "新记录插入失败";
                }
            }
        } else if (type == 2) {
            log.info("处理type=2的情况：没有记录就不做任何操作，有记录就更新");
            // type=2: 没有记录就不做任何操作，有记录就更新
            if (existingRecord == null) {
                // 记录不存在，不做任何操作
                log.info("异常记录不存在，跳过更新操作，oaRequestId: {}", oaRequestId);
                return oaRequestId + "记录不存在，跳过更新操作";
            } else {
                // 记录存在，更新记录
                log.info("异常记录存在，开始更新记录，oaRequestId: {}, 现有记录id: {}", 
                        oaRequestId, existingRecord.getId());
                
                UpdateWrapper<EmsAbnormal> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("oa_request_id", oaRequestId);
                updateWrapper.set("type", type);
                updateWrapper.set("status", status);
                updateWrapper.set("fixed_no", fixNo);
                updateWrapper.set("sequence_id", sequenceId);
                updateWrapper.set("message", message);
                
                log.info("准备更新异常记录，更新内容 - type: {}, status: {}, fixNo: {}, sequenceId: {}, message: {}", 
                        type, status, fixNo, sequenceId, message);
                
                boolean updated = emsAbnormalService.update(updateWrapper);
                if (updated) {
                    log.info("异常记录更新成功，oaRequestId: {}", oaRequestId);
                    return oaRequestId + "记录更新成功";
                } else {
                    log.error("异常记录更新失败，oaRequestId: {}", oaRequestId);
                    return oaRequestId + "记录更新失败";
                }
            }
        } else {
            // 其他type值的处理
            log.error("不支持的type值，oaRequestId: {}, type: {}", oaRequestId, type);
            return oaRequestId + "不支持的type值: " + type;
        }
    }

    /**
     * 更新EBS标志
     */
    private void updateEbsFlags(List<Long> sequenceIds, String ebsUpdateFlag) {
        log.info("========== 开始更新EBS标志 ==========");
        log.info("更新EBS标志，URL: {}, sequenceIds数量: {}", ebsUpdateFlag, sequenceIds.size());
        log.info("需要更新的sequenceIds列表: {}", sequenceIds);
        
        try {
            String jsonBody = JSONUtil.toJsonStr(sequenceIds);
            log.info("更新EBS标志请求体: {}", jsonBody);
            
            HttpResponse oaResponse = HttpRequest.post(ebsUpdateFlag)
                    .header(Header.CONTENT_TYPE, CONTENT_TYPE_JSON)
                    .body(jsonBody)
                    .timeout(HTTP_TIMEOUT)
                    .execute();

            log.info("更新EBS标志请求完成，HTTP状态码: {}", oaResponse.getStatus());
            
            if (oaResponse.getStatus() != 200) {
                log.error("更新EBS flag 请求失败，HTTP状态码: {}, 响应体: {}", 
                        oaResponse.getStatus(), oaResponse.body());
            } else {
                log.info("更新EBS标志成功，HTTP状态码: 200, 响应体: {}", oaResponse.body());
            }
            
            log.info("========== EBS标志更新流程完成 ==========");
        } catch (Exception e) {
            log.error("更新EBS标志时发生错误，sequenceIds: {}, 错误信息: {}", 
                    sequenceIds, e.getMessage(), e);
        }
    }
}